package com.engine.salary.entity.salarysob.bo;

import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.hrm.DeptInfo;
import com.engine.salary.entity.hrm.PositionInfo;
import com.engine.salary.entity.hrm.SubCompanyInfo;
import com.engine.salary.entity.salarysob.dto.SalarySobRangeListDTO;
import com.engine.salary.entity.salarysob.param.SalarySobRangeEmpQueryParam;
import com.engine.salary.entity.salarysob.po.SalarySobRangePO;
import com.engine.salary.enums.salarysob.SalaryEmployeeStatusEnum;
import com.engine.salary.enums.salarysob.TargetTypeEnum;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 薪资账套人员范围
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
public class SalarySobRangeBO {

    /**
     * 将薪资账套的人员范围转换成人员查询参数
     *
     * @param salarySobRanges 薪资账套的人员范围
     * @return
     */
    public static List<SalarySobRangeEmpQueryParam> convert2EmployeeQueryParam(List<SalarySobRangePO> salarySobRanges) {
        if (CollectionUtils.isEmpty(salarySobRanges)) {
            return Collections.emptyList();
        }
        List<SalarySobRangeEmpQueryParam> resultParams = Lists.newArrayListWithExpectedSize(salarySobRanges.size());
        salarySobRanges.stream().forEach( item -> {
            List<String> employeeStatus= new ArrayList<>();
            String[] split = item.getEmployeeStatuses().split(",");
            List<Integer> enumsList = Arrays.asList(split).stream().map(i-> Integer.valueOf(i)).collect(Collectors.toList());
            List<SalaryEmployeeStatusEnum> salaryEmployeeStatusEnums = SalaryEmployeeStatusEnum.parseByValues(enumsList);
            for(SalaryEmployeeStatusEnum e: salaryEmployeeStatusEnums){
                employeeStatus.add(e.getValue().toString());
            }
            TargetTypeEnum targetTypeEnum = TargetTypeEnum.parseByValue(item.getTargetType());
            SalarySobRangeEmpQueryParam queryParam = SalarySobRangeEmpQueryParam.builder()
                    .targetType(Optional.ofNullable(targetTypeEnum).map(TargetTypeEnum::name).orElse(StringUtils.EMPTY))
                    .targetIds(Arrays.asList(item.getTargetId()))
                    .target(item.getTarget())
                    .employeeStatus(employeeStatus)
                    .build();
            resultParams.add(queryParam);
        });
        return resultParams;
    }

    /**
     * 薪资账套的人员范围po转换成人员范围列表dto
     *
     * @param salarySobRanges    薪资账套的人员范围
     * @param employeeComInfos   人员信息
     * @param departmentComInfos 部门信息
     * @param positionComInfos   岗位信息
     * @return
     */
    public static List<SalarySobRangeListDTO> convert2ListDTO(List<SalarySobRangePO> salarySobRanges,
                                                              List<DataCollectionEmployee> employeeComInfos,
                                                              List<DeptInfo> departmentComInfos,
                                                              List<SubCompanyInfo> subCompanyInfos,
                                                              List<PositionInfo> positionComInfos) {
        if (CollectionUtils.isEmpty(salarySobRanges)) {
            return Collections.emptyList();
        }
        Map<Long, String> employeeComInfoMap = SalaryEntityUtil.convert2Map(employeeComInfos, DataCollectionEmployee::getEmployeeId, DataCollectionEmployee::getUsername);
        Map<Long, String> departmentComInfoMap = SalaryEntityUtil.convert2Map(departmentComInfos, DeptInfo::getId, DeptInfo::getName);
        Map<Long, String> subCompanyComInfoMap = SalaryEntityUtil.convert2Map(subCompanyInfos, SubCompanyInfo::getId, SubCompanyInfo::getName);
        Map<Long, String> positionComInfoMap = SalaryEntityUtil.convert2Map(positionComInfos, PositionInfo::getId, PositionInfo::getName);
        return salarySobRanges.stream()
                .map(salarySobRangePO -> {
                    TargetTypeEnum targetTypeEnum = TargetTypeEnum.parseByValue(salarySobRangePO.getTargetType());

                    String employeeStatusesStr = parseByEmployeeStatuses(salarySobRangePO.getEmployeeStatuses());
                    return SalarySobRangeListDTO.builder()
                            .id(salarySobRangePO.getId())
                            .salarySobId(salarySobRangePO.getSalarySobId())
                            .targetType(targetTypeEnum)
                            .targetTypeName(Optional.ofNullable(targetTypeEnum)
                                    .map(e -> SalaryI18nUtil.getI18nLabel(e.getLabelId(), e.getDefaultLabel()))
                                    .orElse(StringUtils.EMPTY))
                            .targetId(salarySobRangePO.getTargetId())
                            .target(salarySobRangePO.getTarget())
                            .targetName(buildTargetName(salarySobRangePO, employeeComInfoMap, departmentComInfoMap, subCompanyComInfoMap, positionComInfoMap))
                            .employeeStatus(employeeStatusesStr)
                            .status(parseByStatuses(salarySobRangePO.getEmployeeStatuses()))
                            .build();
                })
                .collect(Collectors.toList());
    }

    /**
     * 转换employeeStatuses
     *
     * @param employeeStatuses
     * @return
     */
    private static String parseByEmployeeStatuses(String employeeStatuses) {
        String[] split = employeeStatuses.split(",");
        List<Integer> enumsList = Arrays.asList(split).stream().map(item -> Integer.valueOf(item)).collect(Collectors.toList());
        List<SalaryEmployeeStatusEnum> salaryEmployeeStatusEnums = SalaryEmployeeStatusEnum.parseByValues(enumsList);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < salaryEmployeeStatusEnums.size(); i++) {
            sb.append(salaryEmployeeStatusEnums.get(i).getDefaultLabel());
            if (i + 1 != salaryEmployeeStatusEnums.size()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    private static String parseByStatuses(String employeeStatuses) {
        String[] split = employeeStatuses.split(",");
        List<Integer> enumsList = Arrays.asList(split).stream().map(item -> Integer.valueOf(item)).collect(Collectors.toList());
        List<SalaryEmployeeStatusEnum> salaryEmployeeStatusEnums = SalaryEmployeeStatusEnum.parseByValues(enumsList);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < salaryEmployeeStatusEnums.size(); i++) {
            sb.append(salaryEmployeeStatusEnums.get(i));
            if (i + 1 != salaryEmployeeStatusEnums.size()) {
                sb.append(",");
            }
        }
        return sb.toString();
    }

    /**
     * 解析薪资账套人员范围中对象的名称（可能是人员名称、部门名称、岗位名称……）
     *
     * @param salarySobRange       薪资账套的人员范围
     * @param employeeComInfoMap   人员信息
     * @param departmentComInfoMap 部门信息
     * @param positionComInfoMap   岗位信息
     * @return
     */
    private static String buildTargetName(SalarySobRangePO salarySobRange,
                                          Map<Long, String> employeeComInfoMap,
                                          Map<Long, String> departmentComInfoMap,
                                          Map<Long, String> subCompanyComInfoMap,
                                          Map<Long, String> positionComInfoMap) {
        TargetTypeEnum targetTypeEnum = TargetTypeEnum.parseByValue(salarySobRange.getTargetType());
        if (Objects.isNull(targetTypeEnum)) {
            return StringUtils.EMPTY;
        }
        switch (targetTypeEnum) {
            case EMPLOYEE:
                return employeeComInfoMap.getOrDefault(salarySobRange.getTargetId(), StringUtils.EMPTY);
            case DEPT:
                return departmentComInfoMap.getOrDefault(salarySobRange.getTargetId(), StringUtils.EMPTY);
            case SUBCOMPANY:
                return subCompanyComInfoMap.getOrDefault(salarySobRange.getTargetId(), StringUtils.EMPTY);
            case POSITION:
                return positionComInfoMap.getOrDefault(salarySobRange.getTargetId(), StringUtils.EMPTY);
            case SQL:
                return salarySobRange.getTarget();
            default:
                return StringUtils.EMPTY;
        }
    }
}
